package javango.forms.fields;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import javango.forms.Form;
import javango.forms.widgets.Widget;

public class BoundField {

	private Field field;
	private Form form;
	private String name;
	private String htmlName;
	private String verboseName;
	private String helpText;	

	public BoundField(Field field, Form form, String name) {
		super();
		this.field = field;
		this.form = form;
		this.name = name;		
		this.verboseName = StringUtils.isBlank(field.getVerboseName()) ? name : field.getVerboseName();		
		this.htmlName = StringUtils.isBlank(form.getPrefix()) ? name : form.getPrefix() + "-" + name;
		this.helpText = StringUtils.isBlank(field.getHelpText()) ? "" : field.getHelpText();
		
	}
	
	public String getHtmlName() {
		return htmlName;
	}
	
	public List<String> getErrors() {
		// TODO getErrors should really return a list or something,  this is returning a list
		// so that when that day happens this is already almost ready..
		List<String> list = new ArrayList<String>();
		String error = form.getErrors().get(field.getName());
		if (error != null)
			list.add(error);
		return list;
	}
	public Widget getWidget() {
		return field.getWidget();
	}
	public Field getField() {
		return field;
	}

	public String toString() {
		return asWidget(null, null);
	}
	
	public String withAttrs(String stringAttrs ) {
		Map<String, Object> attrs = new LinkedHashMap<String, Object>();
		
		for (String attr : stringAttrs.split(", ")) {
			String[] split = attr.split("=");
			if (split.length == 2) {
				attrs.put(split[0], split[1]);
			} else if (split.length==1) {
				attrs.put(split[0], null);
			} else  {
				// TODO what to do on a bad formatted string...??
			}
		}
		
		if (attrs.isEmpty()) return asWidget(null, null);
		
		return asWidget(null, attrs);
	}
	
	public String asWidget(Widget widget, Map<String, Object> attrs) {
		if (widget == null) {
			if (field.isHidden()) {
				widget = field.getHiddenWidget(); 
			} else {
				widget = field.getWidget();
			}
		}
		
		if (attrs == null) {
			attrs = new LinkedHashMap<String, Object>();
		}
		
		if (StringUtils.isNotBlank(form.getId()) && !attrs.containsKey("id") && !widget.getAttrs().containsKey("id")) {
			attrs.put("id", form.getId());
		}
		if (!field.isEditable()) {
			attrs.put("READONLY", null);
		}
		
		Object dataObject; 
		if (!form.isBound()) {
			Map<String, Object> initial = form.getInitial();
			dataObject = initial.get(name);
			dataObject = dataObject != null ? dataObject : field.getInitial();
		} else {
			dataObject = field.getWidget().valueFromMap(form.getData(), form.getPrefix() == null ? name : form.getPrefix() + "-" + name);
			
		}
		return widget.render(htmlName, dataObject, attrs);
	}

	public String getVerboseName() {
		return verboseName;
	}

	public void setVerboseName(String verboseName) {
		this.verboseName = verboseName;
	}
	
	public boolean isHidden() {
		return field.isHidden();
	}

	public String getHelpText() {
		return helpText;
	}

	public void setHelpText(String helpText) {
		this.helpText = helpText;
	}
}
